package view;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.util.ArrayList;

import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import model.Order;
import model.Stock;

import server.Server;
import server.exception.InvalidOrderException;
import client.Client;

public class SellPanel extends JPanel {
	private static final long serialVersionUID = 7378979806569332679L;
	
	private Client client;
	private Server server;
	
	private JList stockList;
	private DefaultListModel stockListModel;
	private JPanel stockControls;
	private JLabel available;
	
	private JTextField sellQuantity;
	private JTextField sellPrice;
	private JButton sell;
	private JLabel selectedStockPrice;
	private JTextArea buying;
	private ArrayList<Stock> stocks;
	
	public SellPanel() {
		// create GUI components
		stockListModel = new DefaultListModel();
		stockList = new JList(stockListModel);
		stockList.addListSelectionListener(new StockSelectedListener());
		stockControls = new JPanel();
		sellQuantity = new JTextField("0");
		sellPrice = new JTextField("0");
		selectedStockPrice = new JLabel();
		sell = new JButton("Sell Stock");
		sell.addActionListener(new SellListener());
		buying = new JTextArea();
		available = new JLabel();
		
		// initial layout
		setLayout(new BorderLayout());
		add(stockList, BorderLayout.WEST);
		JPanel p = new JPanel(new BorderLayout());
		
		stockControls.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.fill = GridBagConstraints.HORIZONTAL;
		c.insets = new Insets(5, 5, 5, 5);
		c.weightx = 0.5;
		c.gridy = 0;
		
		c.gridy++;
		stockControls.add(new JLabel("Current Price"), c);
		stockControls.add(selectedStockPrice, c);
		
		c.gridy++;
		stockControls.add(new JLabel("You Have"), c);
		stockControls.add(available, c);
		
		c.gridy++;
		stockControls.add(new JLabel("Quantity"), c);
		stockControls.add(sellQuantity, c);

		c.gridy++;
		stockControls.add(new JLabel("Price"), c);
		stockControls.add(sellPrice, c);

		c.gridy++;
		c.gridx = 1;
		stockControls.add(sell, c);
		
		p.add(stockControls, BorderLayout.NORTH);
		p.add(new JScrollPane(buying), BorderLayout.CENTER);
		add(p, BorderLayout.CENTER);
	}
	
	/**
	 * Update the view to show the data
	 * @param s
	 * 		The server object
	 * @param c
	 * 		The client object
	 * @throws RemoteException
	 */
	public void populate(Server s, Client c) throws RemoteException {
		// we dont want an older version of the object
		this.server = s;
		this.client = c;
		
		stocks = server.getStocks(c);
		stockListModel.clear();
		for (Stock stock : stocks) {
			stockListModel.addElement(stock.getName());
		}
		if(!stockListModel.isEmpty()) {
			stockList.setSelectedIndex(0);
		}
	}
	
	/** Listener to handle once stock has been selected **/
	class StockSelectedListener implements ListSelectionListener {

		public void valueChanged(ListSelectionEvent arg0) {
			// need to make sure the stock has at least 1
			if (stockList.getSelectedIndex() >= 0) {
				Stock s = stocks.get(stockList.getSelectedIndex());
				try {
					// get the price
					selectedStockPrice.setText(String.valueOf(s.getPrice()));
					// get the list
					ArrayList<Order> ol = server.getBuyOffers(client, s.getName());
					if (ol != null) {
						buying.setText("");
						// append any valid data to the text field
						for (Order o : ol) {
							buying.append(String.format(
									"Request for %d at %d (%s)\n", o
											.getNumber(), o.getPrice(), o
											.getTransactionId()));
						}
					} else {
						buying.setText("nobody is looking to buy this stock");
					}
					
					// get the number of shares the user has
					int holding = server.getHolding(client, s.getName());
					available.setText(String.valueOf(holding));
				} catch (RemoteException e) {
					JOptionPane.showMessageDialog(SellPanel.this,
							"An error occured while communicating with server: "
									+ e.getMessage(), "Error",
							JOptionPane.ERROR_MESSAGE);
					e.printStackTrace();
				}
			}
		}
	}
	
	/** Listener to handle sell; once it has been selected**/
	class SellListener implements ActionListener {

		public void actionPerformed(ActionEvent arg0) {
			try {
				// get the values the user selected/entered in the available item and
				// Proceed to sell them if possible
				server.sellStock(client, (String)stockList.getSelectedValue(),
						Integer.parseInt(sellQuantity.getText()),
						Integer.parseInt(sellPrice.getText()));
			} catch (NumberFormatException e) {
				JOptionPane.showMessageDialog(SellPanel.this,
						"Please enter a numerical value.", "Error",
						JOptionPane.ERROR_MESSAGE);
			} catch (RemoteException e) {
				JOptionPane.showMessageDialog(SellPanel.this,
						"An error occured while communicating with server: " + e.getMessage(),
						"Error", JOptionPane.ERROR_MESSAGE);
			} catch (InvalidOrderException e) {
				JOptionPane.showMessageDialog(SellPanel.this, e.getMessage(),
						"Error", JOptionPane.ERROR_MESSAGE);
			}

		}

	}

}
